Sensor Fusion for Kinetis MCUs (ISSDK/KSDK version)
sensor_fusion.h
Go to the documentation of this file.
1 // Copyright (c) 2014, 2015, 2016, NXP Semiconductors N.V.,
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of NXP Semiconductors N.V. nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL NXP SEMICONDUCTORS N.V. BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 // Sensor fusion requires a fairly extensive set of data structures, which are
27 // defined in this file. The top level structure is shown near the bottom. The
28 // size of this structure (SensorFusionGlobals) varies dramatically as a function
29 // of which fusion variations have been selected in build.h.
30 
31 /*! \file sensor_fusion.h
32  \brief The sensor_fusion.h file implements the top level programming interface
33 */
34 
35 #ifndef SENSOR_FUSION_TYPES_H
36 #define SENSOR_FUSION_TYPES_H
37 
38 // Standard includes that everyone needs
39 #include "math.h"
40 #include "stdbool.h"
41 #include "stdio.h"
42 #include "stdint.h"
43 #include "Driver_SPI_SDK2.h"
44 
45 #include "issdk_hal.h" // Hardware Abstraction Layer board dependencies beyond those generated in board.h by PEX
46 #include "build.h" // This is where the build parameters are defined
47 #include "magnetic.h" // Magnetic calibration functions/structures
48 #include "precisionAccelerometer.h" // Accel calibration functions/structures
49 #include "orientation.h" // Functions for manipulating orientations
50 
51 /// @name Integer Typedefs
52 /// Typedefs to map common integer types to standard form
53 ///@{
54 typedef unsigned char byte;
55 typedef int8_t int8;
56 typedef int16_t int16;
57 typedef int32_t int32;
58 typedef uint8_t uint8;
59 typedef uint16_t uint16;
60 typedef uint32_t uint32;
61 ///@}
62 
63 /// the quaternion type to be transmitted
64 typedef enum quaternion {
65  Q3, ///< Quaternion derived from 3-axis accel (tilt)
66  Q3M, ///< Quaternion derived from 3-axis mag only (auto compass algorithm)
67  Q3G, ///< Quaternion derived from 3-axis gyro only (rotation)
68  Q6MA, ///< Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
69  Q6AG, ///< Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
70  Q9 ///< Quaternion derived from full 9-axis sensor fusion
72 
73 /// @name Vector Components
74 /// Index values for accessing vector terms
75 ///@{
76 #define CHX 0 ///< Used to access X-channel entries in various data data structures
77 #define CHY 1 ///< Used to access Y-channel entries in various data data structures
78 #define CHZ 2 ///< Used to access Z-channel entries in various data data structures
79 ///@}
80 
81 // booleans
82 #define true 1 ///< Boolean TRUE
83 #define false 0 ///< Boolean FALSE
84 
85 /// @name Generic bit-field values
86 /// Generic bit-field values
87 ///@{
88 #define B0 (1 << 0)
89 #define B1 (1 << 1)
90 #define B2 (1 << 2)
91 #define B3 (1 << 3)
92 ///@}
93 
94 /// @name Math Constants
95 /// useful multiplicative conversion constants
96 ///@{
97 #define PI 3.141592654F ///< pi
98 #define PIOVER2 1.570796327F ///< pi / 2
99 #define FPIOVER180 0.01745329251994F ///< degrees to radians conversion = pi / 180
100 #define F180OVERPI 57.2957795130823F ///< radians to degrees conversion = 180 / pi
101 #define F180OVERPISQ 3282.8063500117F ///< square of F180OVERPI
102 #define ONETHIRD 0.33333333F ///< one third
103 #define ONESIXTH 0.166666667F ///< one sixth
104 #define ONESIXTEENTH 0.0625F ///< one sixteenth
105 #define ONEOVER12 0.083333333F ///< 1 / 12
106 #define ONEOVER48 0.02083333333F ///< 1 / 48
107 #define ONEOVER120 0.0083333333F ///< 1 / 120
108 #define ONEOVER3840 0.0002604166667F ///< 1 / 3840
109 #define ONEOVERSQRT2 0.707106781F ///< 1/sqrt(2)
110 #define SQRT15OVER4 0.968245837F ///< sqrt(15)/4
111 #define GTOMSEC2 9.80665 ///< standard gravity in m/s2
112 ///@}
113 
114 // Placeholder structures (redefined later, but needed now for pointer definitions)
115 struct SensorFusionGlobals; ///< Top level structure has pointers to everything else
116 struct StatusSubsystem; ///< Application-specific status subsystem
117 struct PhysicalSensor; ///< We'll have one of these for each physical sensor (FXOS8700 = 1 physical sensor)
118 struct ControlSubsystem; ///< Application-specific serial communications system
119 
120 typedef enum { /// These are the state definitions for the status subsystem
121  OFF, ///< Application hasn't started
122  INITIALIZING, ///< Initializing sensors and algorithms
123  LOWPOWER, ///< Running in reduced power mode
124  NORMAL, ///< Operation is Nominal
125  RECEIVING_WIRED, ///< Receiving commands over wired interface (momentary)
126  RECEIVING_WIRELESS, ///< Receiving commands over wireless interface (momentary)
127  HARD_FAULT, ///< Non-recoverable FAULT = something went very wrong
128  SOFT_FAULT ///< Recoverable FAULT = something went wrong, but we can keep going
130 
131 // declare typedefs for function prototypes that need to be installed
132 typedef int8_t (initializeSensor_t) (
133  struct PhysicalSensor *sensor,
134  struct SensorFusionGlobals *sfg
135 ) ;
136 typedef int8_t (readSensor_t) (
137  struct PhysicalSensor *sensor,
138  struct SensorFusionGlobals *sfg
139 ) ;
140 typedef int8_t (readSensors_t) (
141  struct SensorFusionGlobals *sfg,
142  uint16_t read_loop_counter
143 ) ;
144 typedef int8_t (installSensor_t) (
145  struct SensorFusionGlobals *sfg, ///< Global data structure pointer
146  struct PhysicalSensor *sensor, ///< SF Structure to store sensor configuration
147  uint16_t addr, ///< I2C address or SPI_ADDR
148  uint16_t schedule, ///< Specifies sampling interval
149  void *bus_driver, ///< I2C or SPI handle
150  initializeSensor_t *initialize, ///< SF Sensor Initialization Function pointer
151  readSensor_t *read ///< SF Sensor Read Function pointer
152 );
153 #define SPI_ADDR 0x00 // Use SPI_ADDR as the address parameter to the installSensor function for SPI-based sensors.
154  // 0x00 is reserved for I2C General Call, and will therefore never occur for any sensor type
155 
157 typedef void (runFusion_t) (struct SensorFusionGlobals *sfg);
158 typedef void (clearFIFOs_t) (struct SensorFusionGlobals *sfg);
160 typedef void (applyPerturbation_t) (struct SensorFusionGlobals *sfg) ;
161 typedef void (setStatus_t) (struct SensorFusionGlobals *sfg, fusion_status_t status);
162 typedef void (updateStatus_t) (struct SensorFusionGlobals *sfg);
163 typedef void (ssSetStatus_t) (struct StatusSubsystem *pStatus, fusion_status_t status);
164 typedef void (ssUpdateStatus_t) (struct StatusSubsystem *pStatus);
165 
166 /// \brief An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo devices = 1)
167 ///
168 /// These structures sit 'on-top-of' the pre-7.0 sensor fusion structures and give us the ability to do run
169 /// time driver installation.
170 typedef struct PhysicalSensor {
171  void *bus_driver; ///< should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI)
172  uint16_t addr; ///< I2C address if applicable
173  uint16_t isInitialized; ///< Bitfields to indicate sensor is active (use SensorBitFields from build.h)
174  spiSlaveSpecificParams_t slaveParams; ///< SPI specific parameters. Not used for I2C.
175  struct PhysicalSensor *next; ///< pointer to next sensor in this linked list
176  uint16_t schedule; ///< Parameter to control sensor sampling rate
177  initializeSensor_t *initialize; ///< pointer to function to initialize sensor using the supplied drivers
178  readSensor_t *read; ///< pointer to function to read sensor using the supplied drivers
180 
181 // Now start "standard" sensor fusion structure definitions
182 
183 /// \brief The PressureSensor structure stores raw and processed measurements for an altimeter.
184 ///
185 /// The PressureSensor structure stores raw and processed measurements, as well as
186 /// metadata for a pressure sensor/altimeter.
187 typedef struct PressureSensor
188 {
189  uint8_t iWhoAmI; ///< sensor whoami
190  bool isEnabled; ///< true if the device is sampling
191  int32_t iH; ///< most recent unaveraged height (counts)
192  int32_t iP; ///< most recent unaveraged pressure (counts)
193  float fH; ///< most recent unaveraged height (m)
194  float fT; ///< most recent unaveraged temperature (C)
195  float fmPerCount; ///< meters per count
196  float fCPerCount; ///< degrees Celsius per count
197  int16_t iT; ///< most recent unaveraged temperature (counts)
199 
200 /// \brief The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
201 ///
202 /// The AccelSensor structure stores raw and processed measurements, as well as metadata
203 /// for a single 3-axis accelerometer. This structure is
204 /// normally "fed" by the sensor driver and "consumed" by the fusion routines.
205 typedef struct AccelSensor
206 {
207  uint8_t iWhoAmI; ///< sensor whoami
208  bool isEnabled; ///< true if the device is sampling
209  uint8_t iFIFOCount; ///< number of measurements read from FIFO
210  uint16_t iFIFOExceeded; ///< Number of samples received in excess of software FIFO size
211  int16_t iGsFIFO[ACCEL_FIFO_SIZE][3]; ///< FIFO measurements (counts)
212  // End of common fields which can be referenced via FifoSensor union type
213  float fGs[3]; ///< averaged measurement (g)
214  float fGc[3]; ///< averaged precision calibrated measurement (g)
215  float fgPerCount; ///< g per count
216  float fCountsPerg; ///< counts per g
217  int16_t iGs[3]; ///< averaged measurement (counts)
218  int16_t iGc[3]; ///< averaged precision calibrated measurement (counts)
219  int16_t iCountsPerg; ///< counts per g
220 } AccelSensor;
221 
222 /// \brief The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor.
223 ///
224 /// The MagSensor structure stores raw and processed measurements, as well as metadata
225 /// for a single 3-axis magnetometer. This structure is
226 /// normally "fed" by the sensor driver and "consumed" by the fusion routines.
227 typedef struct MagSensor
228 {
229  uint8_t iWhoAmI; ///< sensor whoami
230  bool isEnabled; ///< true if the device is sampling
231  uint8_t iFIFOCount; ///< number of measurements read from FIFO
232  uint16_t iFIFOExceeded; ///< Number of samples received in excess of software FIFO size
233  int16_t iBsFIFO[MAG_FIFO_SIZE][3]; ///< FIFO measurements (counts)
234  // End of common fields which can be referenced via FifoSensor union type
235  float fBs[3]; ///< averaged un-calibrated measurement (uT)
236  float fBc[3]; ///< averaged calibrated measurement (uT)
237  float fuTPerCount; ///< uT per count
238  float fCountsPeruT; ///< counts per uT
239  int16_t iBs[3]; ///< averaged uncalibrated measurement (counts)
240  int16_t iBc[3]; ///< averaged calibrated measurement (counts)
241  int16_t iCountsPeruT; ///< counts per uT
242 } MagSensor;
243 
244 /// \brief The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
245 ///
246 /// The GyroSensor structure stores raw and processed measurements, as well as metadata
247 /// for a single 3-axis gyroscope. This structure is
248 /// normally "fed" by the sensor driver and "consumed" by the fusion routines.
249 typedef struct GyroSensor
250 {
251  uint8_t iWhoAmI; ///< sensor whoami
252  bool isEnabled; ///< true if the device is sampling
253  uint8_t iFIFOCount; ///< number of measurements read from FIFO
254  uint16_t iFIFOExceeded; ///< Number of samples received in excess of software FIFO size
255  int16_t iYsFIFO[GYRO_FIFO_SIZE][3]; ///< FIFO measurements (counts)
256  // End of common fields which can be referenced via FifoSensor union type
257  float fYs[3]; ///< averaged measurement (deg/s)
258  float fDegPerSecPerCount; ///< deg/s per count
259  int16_t iCountsPerDegPerSec; ///< counts per deg/s
260  int16_t iYs[3]; ///< average measurement (counts)
261 } GyroSensor;
262 
263 /// \brief The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures.
264 ///
265 /// Common elements include: iWhoAmI, isEnabled, iFIFOCount, iFIFOExceeded and the FIFO itself.
266 typedef union FifoSensor {
270 } FifoSensor;
271 
272 /// The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
273 typedef struct SV_1DOF_P_BASIC
274 {
275  float fLPH; ///< low pass filtered height (m)
276  float fLPT; ///< low pass filtered temperature (C)
277  float fdeltat; ///< fusion time interval (s)
278  float flpf; ///< low pass filter coefficient
279  int32_t systick; ///< systick timer
280  int8_t resetflag; ///< flag to request re-initialization on next pass
282 
283 /// This is the 3DOF basic accelerometer state vector structure.
284 typedef struct SV_3DOF_G_BASIC
285 {
286  // start: elements common to all motion state vectors
287  float fLPPhi; ///< low pass roll (deg)
288  float fLPThe; ///< low pass pitch (deg)
289  float fLPPsi; ///< low pass yaw (deg)
290  float fLPRho; ///< low pass compass (deg)
291  float fLPChi; ///< low pass tilt from vertical (deg)
292  float fLPR[3][3]; ///< low pass filtered orientation matrix
293  Quaternion fLPq; ///< low pass filtered orientation quaternion
294  float fLPRVec[3]; ///< rotation vector
295  float fOmega[3]; ///< angular velocity (deg/s)
296  int32_t systick; ///< systick timer
297  // end: elements common to all motion state vectors
298  float fR[3][3]; ///< unfiltered orientation matrix
299  Quaternion fq; ///< unfiltered orientation quaternion
300  float fdeltat; ///< fusion time interval (s)
301  float flpf; ///< low pass filter coefficient
302  int8_t resetflag; ///< flag to request re-initialization on next pass
304 
305 /// This is the 3DOF basic magnetometer state vector structure/
306 typedef struct SV_3DOF_B_BASIC
307 {
308  // start: elements common to all motion state vectors
309  float fLPPhi; ///< low pass roll (deg)
310  float fLPThe; ///< low pass pitch (deg)
311  float fLPPsi; ///< low pass yaw (deg)
312  float fLPRho; ///< low pass compass (deg)
313  float fLPChi; ///< low pass tilt from vertical (deg)
314  float fLPR[3][3]; ///< low pass filtered orientation matrix
315  Quaternion fLPq; ///< low pass filtered orientation quaternion
316  float fLPRVec[3]; ///< rotation vector
317  float fOmega[3]; ///< angular velocity (deg/s)
318  int32_t systick; ///< systick timer
319  // end: elements common to all motion state vectors
320  float fR[3][3]; ///< unfiltered orientation matrix
321  Quaternion fq; ///< unfiltered orientation quaternion
322  float fdeltat; ///< fusion time interval (s)
323  float flpf; ///< low pass filter coefficient
324  int8_t resetflag; ///< flag to request re-initialization on next pass
326 
327 /// SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
328 typedef struct SV_3DOF_Y_BASIC
329 {
330  // start: elements common to all motion state vectors
331  float fPhi; ///< roll (deg)
332  float fThe; ///< pitch (deg)
333  float fPsi; ///< yaw (deg)
334  float fRho; ///< compass (deg)
335  float fChi; ///< tilt from vertical (deg)
336  float fR[3][3]; ///< unfiltered orientation matrix
337  Quaternion fq; ///< unfiltered orientation quaternion
338  float fRVec[3]; ///< rotation vector
339  float fOmega[3]; ///< angular velocity (deg/s)
340  int32_t systick; ///< systick timer
341  // end: elements common to all motion state vectors
342  float fdeltat; ///< fusion filter sampling interval (s)
343  int8_t resetflag; ///< flag to request re-initialization on next pass
345 
346 /// SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
347 typedef struct SV_6DOF_GB_BASIC
348 {
349  // start: elements common to all motion state vectors
350  float fLPPhi; ///< low pass roll (deg)
351  float fLPThe; ///< low pass pitch (deg)
352  float fLPPsi; ///< low pass yaw (deg)
353  float fLPRho; ///< low pass compass (deg)
354  float fLPChi; ///< low pass tilt from vertical (deg)
355  float fLPR[3][3]; ///< low pass filtered orientation matrix
356  Quaternion fLPq; ///< low pass filtered orientation quaternion
357  float fLPRVec[3]; ///< rotation vector
358  float fOmega[3]; ///< virtual gyro angular velocity (deg/s)
359  int32_t systick; ///< systick timer
360  // end: elements common to all motion state vectors
361  float fR[3][3]; ///< unfiltered orientation matrix
362  Quaternion fq; ///< unfiltered orientation quaternion
363  float fDelta; ///< unfiltered inclination angle (deg)
364  float fLPDelta; ///< low pass filtered inclination angle (deg)
365  float fdeltat; ///< fusion time interval (s)
366  float flpf; ///< low pass filter coefficient
367  int8_t resetflag; ///< flag to request re-initialization on next pass
369 
370 /// SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure.
371 typedef struct SV_6DOF_GY_KALMAN
372 {
373  // start: elements common to all motion state vectors
374  float fPhiPl; ///< roll (deg)
375  float fThePl; ///< pitch (deg)
376  float fPsiPl; ///< yaw (deg)
377  float fRhoPl; ///< compass (deg)
378  float fChiPl; ///< tilt from vertical (deg)
379  float fRPl[3][3]; ///< a posteriori orientation matrix
380  Quaternion fqPl; ///< a posteriori orientation quaternion
381  float fRVecPl[3]; ///< rotation vector
382  float fOmega[3]; ///< average angular velocity (deg/s)
383  int32_t systick; ///< systick timer;
384  // end: elements common to all motion state vectors
385  float fQw6x6[6][6]; ///< covariance matrix Qw
386  float fK6x3[6][3]; ///< kalman filter gain matrix K
387  float fQwCT6x3[6][3]; ///< Qw.C^T matrix
388  float fQv; ///< measurement noise covariance matrix leading diagonal
389  float fZErr[3]; ///< measurement error vector
390  float fqgErrPl[3]; ///< gravity vector tilt orientation quaternion error (dimensionless)
391  float fbPl[3]; ///< gyro offset (deg/s)
392  float fbErrPl[3]; ///< gyro offset error (deg/s)
393  float fAccGl[3]; ///< linear acceleration (g) in global frame
394  float fdeltat; ///< sensor fusion interval (s)
395  float fAlphaOver2; ///< PI / 180 * fdeltat / 2
396  float fAlphaSqOver4; ///< (PI / 180 * fdeltat)^2 / 4
397  float fAlphaSqQvYQwbOver12; ///< (PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
398  float fAlphaQwbOver6; ///< (PI / 180 * fdeltat) * Qwb / 6
399  float fQwbOver3; ///< Qwb / 3
400  float fMaxGyroOffsetChange; ///< maximum permissible gyro offset change per iteration (deg/s)
401  int8_t resetflag; ///< flag to request re-initialization on next pass
403 
404 /// SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector structure.
405 typedef struct SV_9DOF_GBY_KALMAN
406 {
407  // start: elements common to all motion state vectors
408  float fPhiPl; ///< roll (deg)
409  float fThePl; ///< pitch (deg)
410  float fPsiPl; ///< yaw (deg)
411  float fRhoPl; ///< compass (deg)
412  float fChiPl; ///< tilt from vertical (deg)
413  float fRPl[3][3]; ///< a posteriori orientation matrix
414  Quaternion fqPl; ///< a posteriori orientation quaternion
415  float fRVecPl[3]; ///< rotation vector
416  float fOmega[3]; ///< average angular velocity (deg/s)
417  int32_t systick; ///< systick timer;
418  // end: elements common to all motion state vectors
419  float fQw9x9[9][9]; ///< covariance matrix Qw
420  float fK9x6[9][6]; ///< kalman filter gain matrix K
421  float fQwCT9x6[9][6]; ///< Qw.C^T matrix
422  float fZErr[6]; ///< measurement error vector
423  float fQv6x1[6]; ///< measurement noise covariance matrix leading diagonal
424  float fDeltaPl; ///< a posteriori inclination angle from Kalman filter (deg)
425  float fsinDeltaPl; ///< sin(fDeltaPl)
426  float fcosDeltaPl; ///< cos(fDeltaPl)
427  float fqgErrPl[3]; ///< gravity vector tilt orientation quaternion error (dimensionless)
428  float fqmErrPl[3]; ///< geomagnetic vector tilt orientation quaternion error (dimensionless)
429  float fbPl[3]; ///< gyro offset (deg/s)
430  float fbErrPl[3]; ///< gyro offset error (deg/s)
431  float fAccGl[3]; ///< linear acceleration (g) in global frame
432  float fVelGl[3]; ///< velocity (m/s) in global frame
433  float fDisGl[3]; ///< displacement (m) in global frame
434  float fdeltat; ///< sensor fusion interval (s)
435  float fgdeltat; ///< g (m/s2) * fdeltat
436  float fAlphaOver2; ///< PI / 180 * fdeltat / 2
437  float fAlphaSqOver4; ///< (PI / 180 * fdeltat)^2 / 4
438  float fAlphaSqQvYQwbOver12; ///< (PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
439  float fAlphaQwbOver6; ///< (PI / 180 * fdeltat) * Qwb / 6
440  float fQwbOver3; ///< Qwb / 3
441  float fMaxGyroOffsetChange; ///< maximum permissible gyro offset change per iteration (deg/s)
442  int8_t iFirstAccelMagLock; ///< denotes that 9DOF orientation has locked to 6DOF eCompass
443  int8_t resetflag; ///< flag to request re-initialization on next pass
445 
446 /// Excluding SV_1DOF_P_BASIC, Any of the SV_ fusion structures above could
447 /// be cast to type SV_COMMON for dereferencing.
448 typedef struct SV_COMMON {
449  float fPhi; ///< roll (deg)
450  float fThe; ///< pitch (deg)
451  float fPsi; ///< yaw (deg)
452  float fRho; ///< compass (deg)
453  float fChi; ///< tilt from vertical (deg)
454  float fRM[3][3]; ///< orientation matrix
455  Quaternion fq; ///< orientation quaternion
456  float fRVec[3]; ///< rotation vector
457  float fOmega[3]; ///< average angular velocity (deg/s)
458  int32_t systick; ///< systick timer;
459 } SV_COMMON;
460 typedef SV_COMMON *SV_ptr;
461 
462 /// \brief The top level fusion structure
463 ///
464 /// The top level fusion structure grows/shrinks based upon flag definitions
465 /// contained in build.h. These same flags will populate the .iFlags field for
466 /// run-time access.
467 typedef struct SensorFusionGlobals
468 {
469  // Subsystem Pointers
470  ///@{
471  /// @name SubsystemPointers
472  /// The Status and Control subsystems can be used as-is, or completely
473  /// replaced with alternate implementations, as long as those implementations
474  /// provide the same interfaces defined in control.h and status.h.
477  ///@}
478  ///@{
479  /// @name MiscFields
480  uint32_t iFlags; ///< a bit-field of sensors and algorithms used
481  PhysicalSensor *pSensors; ///< a linked list of physical sensors
482  volatile uint8_t iPerturbation; ///< test perturbation to be applied
483  // Book-keeping variables
484  int32_t loopcounter; ///< counter incrementing each iteration of sensor fusion (typically 25Hz)
485  int32_t systick_I2C; ///< systick counter to benchmark I2C reads
486  int32_t systick_Spare; ///< systick counter for counts spare waiting for timing interrupt
487  ///@}
488  ///@{
489  /// @name SensorRelatedStructures
490  /// These structures provide homes for sensor readings, as well as
491  /// various calibration functions. Only those needed for a specific
492  /// build are included.
493 #if F_1DOF_P_BASIC
494  PressureSensor Pressure; ///< pressure sensor storage
495 #endif
496 #if F_USING_ACCEL
497  AccelSensor Accel; ///< accelerometer storage
498  AccelCalibration AccelCal; ///< structures for accel calibration
499  AccelBuffer AccelBuffer; ///< storage for points used for calibration
500 #endif
501 #if F_USING_MAG
502  MagSensor Mag; ///< magnetometer storage
503  MagCalibration MagCal; ///< mag cal storage
504  MagBuffer MagBuffer; ///< mag cal constellation points
505 #endif
506 #if F_USING_GYRO
507  GyroSensor Gyro; ///< gyro storage
508 #endif
509  ///@}
510  ///@{
511  /// @name FusionSpecificStructures
512 #if F_1DOF_P_BASIC
513  SV_1DOF_P_BASIC SV_1DOF_P_BASIC; ///< Pressure
514 #endif
515 #if F_3DOF_G_BASIC
516  SV_3DOF_G_BASIC SV_3DOF_G_BASIC; ///< Gravity
517 #endif
518 #if F_3DOF_B_BASIC
519  SV_3DOF_B_BASIC SV_3DOF_B_BASIC; ///< Magnetic
520 #endif
521 #if F_3DOF_Y_BASIC
523 #endif
524 #if F_6DOF_GB_BASIC // 6DOF accel and mag eCompass: (accel + mag)
525  SV_6DOF_GB_BASIC SV_6DOF_GB_BASIC; ///< eCompass (Gravity + Magnetic)
526 #endif
527 #if F_6DOF_GY_KALMAN
528  SV_6DOF_GY_KALMAN SV_6DOF_GY_KALMAN; ///< 6-axis gravity + angular rates Kalman storage
529 #endif
530 #if F_9DOF_GBY_KALMAN
531  SV_9DOF_GBY_KALMAN SV_9DOF_GBY_KALMAN; ///< 9-axis storage
532 #endif
533  ///@}
534  ///@{
535  /// @name FunctionPointers
536  /// Function pointers (the SF library external interface)
537  installSensor_t *installSensor; ///< function for installing a new sensor into t
538  initializeFusionEngine_t *initializeFusionEngine ; ///< set sensor fusion structures to initial values
539  applyPerturbation_t *applyPerturbation ; ///< apply step function for testing purposes
540  readSensors_t *readSensors; ///< read all physical sensors
541  runFusion_t *runFusion; ///< run the fusion routines
542  conditionSensorReadings_t *conditionSensorReadings; ///< preprocessing step for sensor fusion
543  clearFIFOs_t *clearFIFOs; ///< clear sensor FIFOs
544  setStatus_t *setStatus; ///< change status indicator immediately
545  setStatus_t *queueStatus; ///< queue status change for next regular interval
546  updateStatus_t *updateStatus; ///< status=next status
547  updateStatus_t *testStatus; ///< increment to next enumerated status value (test only)
548  ///@}
550 
551 // The following functions are defined in sensor_fusion.c
553  SensorFusionGlobals *sfg, ///< Global data structure pointer
554  struct StatusSubsystem *pStatusSubsystem, ///< Status subsystem pointer
555  struct ControlSubsystem *pControlSubsystem ///< Control subsystem pointer
556 );
559 /// conditionSensorReadings() transforms raw software FIFO readings into forms that
560 /// can be consumed by the sensor fusion engine. This include sample averaging
561 /// and (in the case of the gyro) integrations, applying hardware abstraction layers,
562 /// and calibration functions.
563 /// This function is normally involved via the "sfg." global pointer.
565  SensorFusionGlobals *sfg ///< Global data structure pointer
566 );
567 void clearFIFOs(
568  SensorFusionGlobals *sfg ///< Global data structure pointer
569 );
572 void zeroArray(
573  struct StatusSubsystem *pStatus, ///< Status subsystem pointer
574  void* data, ///< pointer to array to be zeroed
575  uint16_t size, ///< data type size = 8, 16 or 32
576  uint16_t numElements, ///< number of elements to zero out
577  uint8_t check ///< true if you would like to verify writes, false otherwise
578 );
579 /// \brief conditionSample ensures that we never encounter the maximum negative two's complement
580 /// value for a 16-bit variable (-32768).
581 ///
582 /// conditionSample ensures that we never encounter the maximum negative two's complement
583 /// value for a 16-bit variable (-32768). This value cannot be negated, because the maximum
584 /// positive value is +32767. We need the ability to negate to gaurantee that subsequent
585 /// HAL operations can be run successfully.
586 void conditionSample(
587  int16_t sample[3] ///< 16-bit register value from triaxial sensor read
588 );
589 
590 // The following functions are defined in <hal_board_name>.c.
591 // Please note that these are board-dependent
592 
593 /// \brief addToFifo is called from within sensor driver read functions
594 ///
595 /// addToFifo is called from within sensor driver read functions to transfer new readings into
596 /// the sensor structure corresponding to accel, gyro or mag. This function ensures that the software
597 /// FIFOs are not overrun.
598 ///
599 /// example usage: if (status==SENSOR_ERROR_NONE) addToFifo((FifoSensor*) &(sfg->Mag), MAG_FIFO_SIZE, sample);
600 void addToFifo(
601  FifoSensor *sensor, ///< pointer to structure of type AccelSensor, MagSensor or GyroSensor
602  uint16_t maxFifoSize, ///< the size of the software (not hardware) FIFO
603  int16_t sample[3] ///< the sample to add
604 );
605 /// \brief Apply the accelerometer Hardware Abstraction Layer
606 void ApplyAccelHAL(
607  AccelSensor *Accel ///< pointer to accelerometer logical sensor
608 );
609 /// \brief Apply the magnetometer Hardware Abstraction Layer
610 void ApplyMagHAL(
611  MagSensor *Mag ///< pointer to magnetometer logical sensor
612 );
613 /// \brief Apply the gyroscope Hardware Abstraction Layer
614 void ApplyGyroHAL(
615  GyroSensor *Gyro ///< pointer to gyroscope logical sensor
616 );
617 /// \brief ApplyPerturbation is a reverse unit-step test function
618 ///
619 /// The ApplyPerturbation function applies a user-specified step function to
620 /// prior fusion results which is then "released" in the next fusion cycle.
621 /// When used in conjuction with the NXP Sensor Fusion Toolbox, this provides
622 /// a visual indication of the dynamic behavior of the library. ApplyPerturbation()
623 /// is defined in debug.c.
624 
625 // The following function is defined in debug.c:
627 
628 #include "matrix.h" // this is only down here so we can take advantage of _t style typedefs above
629 
630 #endif // SENSOR_FUSION_TYPES_H
float fChi
tilt from vertical (deg)
float fChiPl
tilt from vertical (deg)
Initializing sensors and algorithms.
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
float flpf
low pass filter coefficient
enum quaternion quaternion_type
the quaternion type to be transmitted
float fThe
pitch (deg)
Quaternion derived from full 9-axis sensor fusion.
Definition: sensor_fusion.h:70
float fDeltaPl
a posteriori inclination angle from Kalman filter (deg)
Quaternion fq
unfiltered orientation quaternion
void( setStatus_t)(struct SensorFusionGlobals *sfg, fusion_status_t status)
fusion_status_t status
Current status.
Definition: status.h:47
void conditionSensorReadings(SensorFusionGlobals *sfg)
conditionSensorReadings() transforms raw software FIFO readings into forms that can be consumed by th...
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
struct AccelSensor AccelSensor
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
int8_t resetflag
flag to request re-initialization on next pass
float fLPH
low pass filtered height (m)
int8_t( readSensor_t)(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
float fLPPhi
low pass roll (deg)
float fdeltat
fusion time interval (s)
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
float fAlphaQwbOver6
(PI / 180 * fdeltat) * Qwb / 6
void addToFifo(FifoSensor *sensor, uint16_t maxFifoSize, int16_t sample[3])
addToFifo is called from within sensor driver read functions
Quaternion fq
orientation quaternion
clearFIFOs_t * clearFIFOs
clear sensor FIFOs
int32_t systick_I2C
systick counter to benchmark I2C reads
bool isEnabled
true if the device is sampling
float fPsiPl
yaw (deg)
float fLPPsi
low pass yaw (deg)
union FifoSensor FifoSensor
The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures...
float fThePl
pitch (deg)
Quaternion fq
unfiltered orientation quaternion
uint32_t iFlags
a bit-field of sensors and algorithms used
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
float fThe
pitch (deg)
struct PhysicalSensor PhysicalSensor
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
void initSensorFusionGlobals(SensorFusionGlobals *sfg, struct StatusSubsystem *pStatusSubsystem, struct ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
Definition: sensor_fusion.c:68
int16_t iT
most recent unaveraged temperature (counts)
int32_t systick
systick timer
float fdeltat
fusion time interval (s)
float fAlphaSqQvYQwbOver12
(PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
Receiving commands over wireless interface (momentary)
float fCountsPerg
counts per g
Functions to convert between various orientation representations.
struct MagSensor MagSensor
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
int32_t systick
systick timer
int16_t iCountsPerDegPerSec
counts per deg/s
MagSensor Mag
Quaternion derived from 3-axis mag only (auto compass algorithm)
Definition: sensor_fusion.h:66
float fChi
tilt from vertical (deg)
MagCalibration MagCal
mag cal storage
Implements accelerometer calibration routines.
uint8_t iFIFOCount
number of measurements read from FIFO
void conditionSample(int16_t sample[3])
conditionSample ensures that we never encounter the maximum negative two&#39;s complement value for a 16-...
Quaternion fqPl
a posteriori orientation quaternion
Quaternion fLPq
low pass filtered orientation quaternion
struct GyroSensor GyroSensor
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
The top level fusion structure.
float fLPPhi
low pass roll (deg)
int8_t( initializeSensor_t)(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
float fdeltat
fusion time interval (s)
float fmPerCount
meters per count
float fLPRho
low pass compass (deg)
int32_t iP
most recent unaveraged pressure (counts)
installSensor_t * installSensor
function for installing a new sensor into t
float fLPRho
low pass compass (deg)
int8_t resetflag
flag to request re-initialization on next pass
int8_t resetflag
flag to request re-initialization on next pass
float fAlphaSqOver4
(PI / 180 * fdeltat)^2 / 4
void * bus_driver
should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) ...
float fLPPsi
low pass yaw (deg)
#define MAG_FIFO_SIZE
FXOS8700 (mag), MAG3110 have no FIFO so equivalent to 1 element FIFO.
StatusSubsystem() provides an object-like interface for communicating status to the user...
Definition: status.h:44
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
Quaternion derived from 3-axis gyro only (rotation)
Definition: sensor_fusion.h:67
These are the state definitions for the status subsystem.
int16_t iCountsPeruT
counts per uT
void testStatus(SensorFusionGlobals *sfg)
Definition: sensor_fusion.c:62
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
Definition: sensor_fusion.h:68
This is the 3DOF basic accelerometer state vector structure.
uint8_t uint8
Definition: sensor_fusion.h:58
int32_t int32
Definition: sensor_fusion.h:57
int16_t iCountsPerg
counts per g
readSensor_t * read
pointer to function to read sensor using the supplied drivers
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
Definition: sensor_fusion.h:69
#define ACCEL_FIFO_SIZE
FXOS8700 (accel), MMA8652, FXLS8952 all have 32 element FIFO.
struct SV_3DOF_G_BASIC SV_3DOF_G_BASIC
This is the 3DOF basic accelerometer state vector structure.
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
float fLPThe
low pass pitch (deg)
void ApplyGyroHAL(GyroSensor *Gyro)
Apply the gyroscope Hardware Abstraction Layer.
readSensors_t * readSensors
read all physical sensors
float fMaxGyroOffsetChange
maximum permissible gyro offset change per iteration (deg/s)
struct ControlSubsystem * pControlSubsystem
Magnetic Calibration Structure.
Definition: magnetic.h:72
runFusion_t runFusion
int8_t( readSensors_t)(struct SensorFusionGlobals *sfg, uint16_t read_loop_counter)
float fgdeltat
g (m/s2) * fdeltat
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
MagSensor Mag
magnetometer storage
uint32_t uint32
Definition: sensor_fusion.h:60
float fcosDeltaPl
cos(fDeltaPl)
Quaternion fLPq
low pass filtered orientation quaternion
float fPhiPl
roll (deg)
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
float fThePl
pitch (deg)
This is the 3DOF basic magnetometer state vector structure/.
float fDelta
unfiltered inclination angle (deg)
quaternion structure definition
Definition: orientation.h:37
uint16_t schedule
Parameter to control sensor sampling rate.
#define GYRO_FIFO_SIZE
FXAX21000, FXAS21002 have 32 element FIFO.
Recoverable FAULT = something went wrong, but we can keep going.
int8_t resetflag
flag to request re-initialization on next pass
int32_t iH
most recent unaveraged height (counts)
float fPsiPl
yaw (deg)
The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures...
float fLPChi
low pass tilt from vertical (deg)
float fLPPsi
low pass yaw (deg)
AccelSensor Accel
updateStatus_t * updateStatus
status=next status
The PressureSensor structure stores raw and processed measurements for an altimeter.
float fLPThe
low pass pitch (deg)
initializeFusionEngine_t initializeFusionEngine
uint8_t iWhoAmI
sensor whoami
struct PhysicalSensor * next
pointer to next sensor in this linked list
float fPhiPl
roll (deg)
struct SV_6DOF_GY_KALMAN SV_6DOF_GY_KALMAN
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
float fRho
compass (deg)
quaternion
the quaternion type to be transmitted
Definition: sensor_fusion.h:64
float fLPT
low pass filtered temperature (C)
float fuTPerCount
uT per count
Quaternion fq
unfiltered orientation quaternion
float fRhoPl
compass (deg)
float fAlphaQwbOver6
(PI / 180 * fdeltat) * Qwb / 6
initializeSensor_t * initialize
pointer to function to initialize sensor using the supplied drivers
bool isEnabled
true if the device is sampling
float fMaxGyroOffsetChange
maximum permissible gyro offset change per iteration (deg/s)
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
float flpf
low pass filter coefficient
float fAlphaSqOver4
(PI / 180 * fdeltat)^2 / 4
void ApplyAccelHAL(AccelSensor *Accel)
Apply the accelerometer Hardware Abstraction Layer.
float fsinDeltaPl
sin(fDeltaPl)
float fChiPl
tilt from vertical (deg)
struct SV_1DOF_P_BASIC SV_1DOF_P_BASIC
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
int32_t systick
systick timer
int8_t( installSensor_t)(struct SensorFusionGlobals *sfg, struct PhysicalSensor *sensor, uint16_t addr, uint16_t schedule, void *bus_driver, initializeSensor_t *initialize, readSensor_t *read)
void( clearFIFOs_t)(struct SensorFusionGlobals *sfg)
void( ssUpdateStatus_t)(struct StatusSubsystem *pStatus)
Receiving commands over wired interface (momentary)
Running in reduced power mode.
int32_t systick
systick timer;
struct PressureSensor PressureSensor
The PressureSensor structure stores raw and processed measurements for an altimeter.
float fLPChi
low pass tilt from vertical (deg)
Matrix manipulation functions.
Lower level magnetic calibration interface.
float fdeltat
sensor fusion interval (s)
uint8_t iFIFOCount
number of measurements read from FIFO
float fdeltat
sensor fusion interval (s)
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:64
float fLPThe
low pass pitch (deg)
Quaternion fq
unfiltered orientation quaternion
accelerometer measurement buffer
void( ssSetStatus_t)(struct StatusSubsystem *pStatus, fusion_status_t status)
float fH
most recent unaveraged height (m)
float fCPerCount
degrees Celsius per count
void( conditionSensorReadings_t)(struct SensorFusionGlobals *sfg)
float fQwbOver3
Qwb / 3.
unsigned char byte
Definition: sensor_fusion.h:54
struct SV_3DOF_B_BASIC SV_3DOF_B_BASIC
This is the 3DOF basic magnetometer state vector structure/.
spiSlaveSpecificParams_t slaveParams
SPI specific parameters. Not used for I2C.
int8_t resetflag
flag to request re-initialization on next pass
int8_t resetflag
flag to request re-initialization on next pass
float fPhi
roll (deg)
int8_t iFirstAccelMagLock
denotes that 9DOF orientation has locked to 6DOF eCompass
float fQwbOver3
Qwb / 3.
void( updateStatus_t)(struct SensorFusionGlobals *sfg)
MagBuffer MagBuffer
mag cal constellation points
void ApplyMagHAL(MagSensor *Mag)
Apply the magnetometer Hardware Abstraction Layer.
uint8_t iWhoAmI
sensor whoami
readSensors_t readSensors
struct SensorFusionGlobals SensorFusionGlobals
The top level fusion structure.
runFusion_t * runFusion
run the fusion routines
struct StatusSubsystem * pStatusSubsystem
float fCountsPeruT
counts per uT
Non-recoverable FAULT = something went very wrong.
float fdeltat
fusion filter sampling interval (s)
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
float fLPChi
low pass tilt from vertical (deg)
void( applyPerturbation_t)(struct SensorFusionGlobals *sfg)
void( initializeFusionEngine_t)(struct SensorFusionGlobals *sfg)
float fPsi
yaw (deg)
uint8_t iFIFOCount
number of measurements read from FIFO
float fAlphaOver2
PI / 180 * fdeltat / 2.
GyroSensor Gyro
float fRho
compass (deg)
struct SV_6DOF_GB_BASIC SV_6DOF_GB_BASIC
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
struct SV_3DOF_Y_BASIC SV_3DOF_Y_BASIC
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
uint16_t isInitialized
Bitfields to indicate sensor is active (use SensorBitFields from build.h)
float fPhi
roll (deg)
uint16_t uint16
Definition: sensor_fusion.h:59
Quaternion fqPl
a posteriori orientation quaternion
float fLPDelta
low pass filtered inclination angle (deg)
uint8_t iWhoAmI
sensor whoami
Quaternion fLPq
low pass filtered orientation quaternion
installSensor_t installSensor
float fdeltat
fusion time interval (s)
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:65
float fT
most recent unaveraged temperature (C)
float fgPerCount
g per count
setStatus_t * queueStatus
queue status change for next regular interval
float fLPRho
low pass compass (deg)
float fAlphaOver2
PI / 180 * fdeltat / 2.
SV_COMMON * SV_ptr
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
float fRhoPl
compass (deg)
fusion_status_t
Application-specific serial communications system.
int8_t resetflag
flag to request re-initialization on next pass
float flpf
low pass filter coefficient
setStatus_t * setStatus
change status indicator immediately
int16_t int16
Definition: sensor_fusion.h:56
struct AccelBuffer AccelBuffer
accelerometer measurement buffer
float fPsi
yaw (deg)
The Magnetometer Measurement Buffer holds a 3-dimensional "constellation" of data points...
Definition: magnetic.h:63
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
struct SV_9DOF_GBY_KALMAN SV_9DOF_GBY_KALMAN
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
uint8_t iWhoAmI
sensor whoami
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
int32_t systick
systick timer
Operation is Nominal.
float fQv
measurement noise covariance matrix leading diagonal
float fDegPerSecPerCount
deg/s per count
bool isEnabled
true if the device is sampling
int32_t systick
systick timer;
float fLPPhi
low pass roll (deg)
Excluding SV_1DOF_P_BASIC, Any of the SV_ fusion structures above could be cast to type SV_COMMON for...
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
uint16_t addr
I2C address if applicable.
precision accelerometer calibration structure
void( runFusion_t)(struct SensorFusionGlobals *sfg)
float flpf
low pass filter coefficient
int8_t int8
Definition: sensor_fusion.h:55
struct SV_COMMON SV_COMMON
Excluding SV_1DOF_P_BASIC, Any of the SV_ fusion structures above could be cast to type SV_COMMON for...
volatile uint8_t iPerturbation
test perturbation to be applied
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
applyPerturbation_t ApplyPerturbation
ApplyPerturbation is a reverse unit-step test function.
PhysicalSensor * pSensors
a linked list of physical sensors
int32_t systick
systick timer
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
void zeroArray(struct StatusSubsystem *pStatus, void *data, uint16_t size, uint16_t numElements, uint8_t check)
bool isEnabled
true if the device is sampling
float fAlphaSqQvYQwbOver12
(PI / 180 * fdeltat)^2 * (QvY + Qwb) / 12
int32_t systick
systick timer;